using System.Reflection;
using Synapse.Framework.AoP.Attributes.Core;

namespace Synapse.Framework.AoP
{
    internal class ExecuteCheck : IExecuteCheck
    {
        private readonly object instance;

        public ExecuteCheck(object instance)
        {
            this.instance = instance;
        }

        public void ForParameters(MethodInfo methodInfo, object[] values)
        {
            var parametersInfo = methodInfo.GetParameters();
            var argumentIndex = 0;
            foreach (var parameterInfo in parametersInfo)
            {
                CheckAttributes(methodInfo, parameterInfo, values[argumentIndex]);
                argumentIndex++;
            }
        }

        public void ForReturnValue(MethodInfo methodInfo, object returnValue)
        {
            var parameterInfo = methodInfo.ReturnParameter;
            CheckAttributes(methodInfo, parameterInfo, returnValue);
        }

        private void CheckAttributes(MethodInfo methodInfo, ParameterInfo parameterInfo, object value)
        {
            var attributes = parameterInfo.GetCustomAttributes(typeof(IArgumentAttribute), true);
            foreach (IArgumentAttribute attribute in attributes)
            {
                attribute.Check(new InvocationArgument(instance, methodInfo, parameterInfo, value));
            }
        }

    }
}